/// 创建者：王增阳
/// 开发者：王增阳
/// 版本：1.0
/// 创建日期：2020-02-14
///
/// 小按钮

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:zhibao_flutter/util/check/click_event.dart';
import 'package:zhibao_flutter/util/my_theme.dart';
import 'package:zhibao_flutter/widget/bt/Inkwell_without_color.dart';

const Color _kDisabledBackground = Color(0xFFA9A9A9);
const Color _kDisabledForeground = Color(0xFFD1D1D1);
const double kMinInteractiveDimensionMagic = 44.0;

const EdgeInsets _kButtonPadding = EdgeInsets.all(16.0);
const EdgeInsets _kBackgroundButtonPadding =
    EdgeInsets.symmetric(vertical: 10.0, horizontal: 64.0);

class SmallButton extends StatefulWidget {
  const SmallButton({
    Key? key,
    this.child,
    this.padding,
    this.margin = const EdgeInsets.all(0),
    this.width,
    this.height,
    this.color,
    this.disabledColor = const Color(0xffEFEFEF),
    this.minWidth = kMinInteractiveDimensionMagic,
    this.minHeight = kMinInteractiveDimensionMagic,
    this.pressedOpacity = 1,
    this.borderRadius,
    this.boxShadow,
    this.isShadow = false,
    this.enabled = true,
    this.shadowColor,
    this.border,
    this.gradient,
    this.useInkwell = false,
    this.isNeedLogin = false,
    required this.onPressed,
  })  : assert(pressedOpacity == null ||
            (pressedOpacity >= 0.0 && pressedOpacity <= 1.0)),
        _filled = false,
        super(key: key);

  final Widget? child;
  final EdgeInsetsGeometry? padding;
  final EdgeInsetsGeometry? margin;
  final Color? color;
  final Color? disabledColor;
  final VoidCallback onPressed;
  final double minWidth;
  final double minHeight;
  final double? width;
  final double? height;
  final double? pressedOpacity;
  final BorderRadius? borderRadius;
  final bool _filled;
  final bool isShadow;
  final bool enabled;
  final Color? shadowColor;
  final BoxBorder? border;
  final Gradient? gradient;
  final bool isNeedLogin;
  final bool useInkwell;
  final List<BoxShadow>? boxShadow;

  @override
  _SmallButtonState createState() => _SmallButtonState();

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties
        .add(FlagProperty('enabled', value: enabled, ifFalse: 'disabled'));
  }
}

class _SmallButtonState extends State<SmallButton>
    with SingleTickerProviderStateMixin {
  static const Duration kFadeOutDuration = Duration(milliseconds: 10);
  static const Duration kFadeInDuration = Duration(milliseconds: 100);
  final Tween<double> _opacityTween = Tween<double>(begin: 1.0);

  late AnimationController? _animationController;
  late Animation<double> _opacityAnimation;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      duration: const Duration(milliseconds: 200),
      value: 0.0,
      vsync: this,
    );
    _opacityAnimation = _animationController!
        .drive(CurveTween(curve: Curves.decelerate))
        .drive(_opacityTween);
    _setTween();
  }

  @override
  void didUpdateWidget(SmallButton old) {
    super.didUpdateWidget(old);
    _setTween();
  }

  void _setTween() {
    _opacityTween.end = widget.pressedOpacity ?? 1.0;
  }

  @override
  void dispose() {
    _animationController!.dispose();
    _animationController = null;
    super.dispose();
  }

  bool _buttonHeldDown = false;

  void _handleTapDown(TapDownDetails event) {
    if (!_buttonHeldDown) {
      _buttonHeldDown = true;
      _animate();
    }
  }

  void _handleTapUp(TapUpDetails event) {
    if (_buttonHeldDown) {
      _buttonHeldDown = false;
      _animate();
    }
  }

  void _handleTapCancel() {
    if (_buttonHeldDown) {
      _buttonHeldDown = false;
      _animate();
    }
  }

  void _animate() {
    if (_animationController!.isAnimating) return;
    final bool wasHeldDown = _buttonHeldDown;
    final TickerFuture ticker = _buttonHeldDown
        ? _animationController!.animateTo(1.0, duration: kFadeOutDuration)
        : _animationController!.animateTo(0.0, duration: kFadeInDuration);
    ticker.then<void>((void value) {
      if (mounted && wasHeldDown != _buttonHeldDown) _animate();
    });
  }

  @override
  Widget build(BuildContext context) {
    final Color color = widget.color ?? MyTheme.themeColor();
    final bool enabled = widget.enabled;
    final Color primaryColor = CupertinoTheme.of(context).primaryColor;
    final Color backgroundColor = color;
    final Color foregroundColor = backgroundColor != null
        ? CupertinoTheme.of(context).primaryContrastingColor
        : enabled
            ? primaryColor
            : _kDisabledForeground;
    final TextStyle textStyle = CupertinoTheme.of(context)
        .textTheme
        .textStyle
        .copyWith(color: enabled ? foregroundColor : MyTheme.themeColor()[300]);
    Color resultColor = backgroundColor != null && !enabled
        ? widget.disabledColor ?? _kDisabledBackground
        : backgroundColor;

    final BorderRadius borderRadiusUse =
        widget.borderRadius ?? BorderRadius.circular(24.0);
    final viewResult = Semantics(
      button: true,
      child: ConstrainedBox(
        constraints: widget.minWidth == null || widget.minHeight == null
            ? const BoxConstraints()
            : BoxConstraints(
                minWidth: widget.minWidth, minHeight: widget.minHeight),
        child: FadeTransition(
          opacity: _opacityAnimation,
          child: DecoratedBox(
            decoration: BoxDecoration(
              borderRadius: borderRadiusUse,
              color: widget.gradient != null ? null : resultColor,
              gradient: widget.gradient,
              boxShadow: widget.boxShadow ??
                  (widget.isShadow
                      ? [
                          BoxShadow(
                              color: widget.shadowColor!,
                              offset: Offset(0, 0),
                              blurRadius: 10,
                              spreadRadius: 0.5),
                        ]
                      : []),
              border: widget.border,
            ),
            child: Padding(
              padding: widget.padding ??
                  (backgroundColor != null
                      ? _kBackgroundButtonPadding
                      : _kButtonPadding),
              child: Center(
                widthFactor: 1.0,
                heightFactor: 1.0,
                child: DefaultTextStyle(
                  style: textStyle,
                  child: IconTheme(
                    data: IconThemeData(color: foregroundColor),
                    child: widget.child!,
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
    return Container(
      margin: widget.margin,
      width: widget.width,
      height: widget.height,
      decoration: BoxDecoration(borderRadius: borderRadiusUse),
      child: widget.useInkwell
          ? InkwellWithOutColor(
              onTap: () {
                widget.onPressed();
              },
              child: viewResult)
          : widget.isNeedLogin
              ? ClickEvent(
                  onTap: () async {
                    return widget.onPressed();
                  },
                  child: viewResult)
              : ClickEvent(
                  onTap: () async {
                    return widget.onPressed();
                  },
                  child: viewResult,
                ),
    );
  }
}
